package handlers

import (
	"battle-server/config"
	"errors"
	"game-server/interfaces"
	"game-server/manager"
	"game-server/message"
	"game-server/model"
	"log"
	pb "pb/proto"
	"pb/protocol"
	"time"

	"google.golang.org/protobuf/proto"
)

// 常量定义
const (
	defaultFormationCount = 4 // 默认阵容位置数量
)

// HandlerFormationInfo 处理获取阵容信息请求
func HandlerFormationInfo(client interfaces.IClient, msg message.IMessage) error {
	playerID := client.GetID()

	// 查询玩家阵容信息
	formations, err := GetPlayerFormations(playerID)
	if err != nil {
		log.Printf("查询玩家布阵信息错误: %v", err)
		return err
	}

	// 如果阵容为空，创建默认阵容
	if len(formations) == 0 {
		formations, err = createDefaultFormations(playerID)
		if err != nil {
			log.Printf("创建默认阵容失败: %v", err)
			return err
		}
	}

	// 转换为protobuf消息并发送
	return sendFormationResponse(client, formations)
}

// HandlerFormationAdjust 处理调整阵容请求
func HandlerFormationAdjust(client interfaces.IClient, msg message.IMessage) error {
	// 解析请求
	req := &pb.FormationAdjustReq{}
	if err := proto.Unmarshal(msg.GetData(), req); err != nil {
		log.Printf("解析玩家阵容数据失败: %v", err)
		return err
	}

	playerID := client.GetID()

	// 查询玩家阵容信息
	formations, err := GetPlayerFormations(playerID)
	if err != nil {
		log.Printf("查询玩家布阵信息错误: %v", err)
		return err
	}

	// 检查阵容是否已初始化
	if len(formations) == 0 {
		return errors.New("没有初始化阵容")
	}

	// 检查参数是否合理
	for _, info := range req.Infos {
		heroConfig := manager.GetHeroByID(int(info.HeroId))
		if heroConfig == nil {
			return errors.New("参数异常，请检查")
		}
	}

	// 更新阵容
	if err := updateFormations(formations, req.Infos); err != nil {
		log.Printf("更新阵容失败: %v", err)
		return err
	}

	// 保存到数据库
	if err := saveFormations(formations); err != nil {
		log.Printf("保存阵容失败: %v", err)
		return err
	}

	// 转换为protobuf消息并发送
	return sendFormationResponse(client, formations)
}

// getPlayerFormations 获取玩家阵容信息
func GetPlayerFormations(playerID uint) ([]*model.Formation, error) {
	var formations []*model.Formation
	result := config.DB.Where("player_id = ?", playerID).Find(&formations)
	if result.Error != nil {
		return nil, result.Error
	}
	return formations, nil
}

// createDefaultFormations 创建默认阵容
func createDefaultFormations(playerID uint) ([]*model.Formation, error) {
	formations := make([]*model.Formation, 0, defaultFormationCount)
	now := time.Now()

	for pos := 1; pos <= defaultFormationCount; pos++ {
		formation := &model.Formation{
			PlayerId:   playerID,
			Position:   uint(pos),
			UpdateTime: now,
			CreateTime: now,
		}
		formations = append(formations, formation)
	}

	// 批量插入数据库
	if err := config.DB.Create(formations).Error; err != nil {
		return nil, err
	}

	return formations, nil
}

// updateFormations 更新阵容信息
func updateFormations(formations []*model.Formation, formationInfos []*pb.FormationPB) error {
	// 创建位置到阵容的映射，方便查找
	formationMap := make(map[int32]*model.Formation)
	for _, formation := range formations {
		formationMap[int32(formation.Position)] = formation
	}

	// 更新阵容
	for _, info := range formationInfos {
		if formation, ok := formationMap[info.Position]; ok {
			formation.HeroId = uint(info.HeroId)
			formation.UpdateTime = time.Now()
		}
	}

	return nil
}

// saveFormations 保存阵容到数据库
func saveFormations(formations []*model.Formation) error {
	return config.DB.Save(formations).Error
}

// sendFormationResponse 发送阵容响应
func sendFormationResponse(client interfaces.IClient, formations []*model.Formation) error {
	// 转换为protobuf消息
	formationPB := make([]*pb.FormationPB, 0, len(formations))
	for _, f := range formations {
		p := &pb.FormationPB{
			HeroId:   int32(f.HeroId),
			Position: int32(f.Position),
		}
		formationPB = append(formationPB, p)
	}

	formationRes := &pb.FormationRes{
		Infos: formationPB,
	}

	// 序列化Protobuf消息
	data, err := proto.Marshal(formationRes)
	if err != nil {
		log.Printf("序列化FormationRes错误: %v", err)
		return err
	}

	// 创建并发送消息
	responseMsg := message.NewMessage(protocol.S_C_FORMATION_INFO, data)
	return client.SendMessage(responseMsg.GetData())
}
